返回设计模式博客目录
|
第一篇:单一职责原则
第二篇:开闭原则
第三篇:里氏替换原则
第四篇:依赖倒置原则
第五篇:接口隔离原则
第六篇:迪米特原则
迪米特原则
英文全称为 Law of Demeter,LOD,也称为最少知识原则,意思都是一个对象应该对其他对象有最少的了解。通俗的讲,一个类应该对自己需要耦合或调用的类知道得最少,类的内部如何实现与调用者或者依赖者没关系,调用者或者依赖者只需要知道它需要的方法即可,其他的可一概不用管。类与类之间的关系越密切,耦合越大,当一个类发生变化时,对另一个类的影响也越大。
迪米特原则还有一个英文解释是 Only talk to your immediate friends,翻译过来就是:只与直接的朋友通信。什么叫做直接的朋友?每个对象都必然会与其他对象有耦合关系,两个对象之间的耦合就成为了朋友关系,这种关系的类型有很多,如组合、聚合、依赖等。
下面我们就以租房为例来讲讲迪米特原则的应用。
举例:在北京租房
在北京租房绝大多数都是通过中介找房。我们设定的情况为:我只要求房间的面积和租金,其他的一概不管,中介将符合我们要求的房子提供给我就可以。下面我们看看这个示例。
从上面的代码可以看到,Tenant 不仅依赖了 Mediator 类,还需要频繁地与 Room 类打交道。租户类的要求只是通过中介找到一间适合自己的房间罢了,如果把这些检测条件都放在 Tenant 类中,那么中介类的功能就被弱化,而且导致了 Tenant 与 Room 的耦合较高,因为 Tenant 必须知道许多关于 Room 的细节。当 Room 变化时 Tenant 也必须跟着变化。Tenant 又与 Mediator 耦合,这就出现了纠缠不清的关系。这个时候就需要我们分清谁才是我们真正的“朋友”,在我们所设定的情况下,显然是 Mediator。上述代码的结构下图所示。
既然是耦合太严重,那我们就只能解耦了。首先要明确的是,我们只和我们的朋友通信,这里就是指 Mediator 对象。必须将 Room 相关的操作从 Tenant 中移除,而这些操作案例应该属于 Mediator。我们进行如下重构。
重构后的结构图如下所示。
只是将对于 Room 的判定操作移到了 Mediator 类中,这本应该是 Mediator 的职责,根据租户设定的条件查找符合要求的房子,并且将结果交给租户就可以了。租户并不需要知道太多关于 Room 的细节,比如与房东签合同,房东的房产证是不是真的,房内的设施坏了之后要找谁谁修等。当我们通过我们的“朋友”——中介租了房之后,所有的事情我们都通过与中介沟通就好了,房东、维修师傅等这些角色并不是我们直接的“朋友”。“只与直接的朋友通信”这简单的几个字就能够将我们从复杂的关系网中抽离出来,使程序耦合度更低、稳定性更好。
举例二:ImageCache
前面博客中的图片加载器项目,ImageCache 就是用户的直接朋友,而 SD 卡缓存内部使用了 FileOutputStream,这个 FileOutputStream 就不属于用户的直接朋友了。因此,用户完全不知道它的存在,用户只需要与 ImageCache 对象打交的即可。将图片存到 SD 卡中的代码如下。
现在领导要求使用 jake wharton 的 DiskLruCache 来替换 FileOutputStream。代码如下:
SD 卡缓存的具体实现虽然被替换了,但用户根本不会感知到。因为用户根本不知道 FileOutputStream 和 DiskLruCache 的存在,他们没有与 FileOutputStream 或 DiskLruCache 进行通信,他们只认识直接“朋友”——ImageCache,ImageCache 将一切细节隐藏在直接“朋友”的外衣之下,使得系统具有更低的耦合性和更好的可扩展性。